package soulkun.library.custom.view;

import android.content.Context
import android.util.AttributeSet
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import soulkun.library.utils.R
import soulkun.library.utils.toPx
import soulkun.library.utils.toPxF
import kotlin.properties.Delegates

/**
 * type —— 图片形状类型
 * radius —— 图片圆角度数
 */
class RoundOvalImageView: androidx.appcompat.widget.AppCompatImageView {

    companion object{
        const val TAG = "RoundOvalImageView"
        const val TYPE_CIRCLE = 0 // 圆形
        const val TYPE_ROUND = 1 // 圆角矩形
        const val TYPE_OVAL = 2 //椭圆形
    }

    /**
     * 设置图片类型：圆形、圆角矩形、椭圆形
     */
    var type: Int
        get() = mType
        set(mType) {
            if (this.mType != mType) {
                this.mType = mType
                invalidate()
            }
        }

    /**
     * 设置圆角大小
     * @parammRoundRadius
     */
    var roundRadius: Int
        get() = mRoundRadius
        set(mRoundRadius) {
            if (this.mRoundRadius != mRoundRadius) {
                this.mRoundRadius = mRoundRadius
                invalidate()
            }
        }

    private var mType by Delegates.notNull<Int>() // 形状选择
    private var mRoundRadius by Delegates.notNull<Int>() // 圆角大小

    private lateinit var mPaint: Paint
    private var minSize = 0
    private var mRadius = 0 //圆半径
    private lateinit var mRect: RectF //矩形凹行大小
    private lateinit var mBitmapShader: BitmapShader//图形渲染
    private lateinit var mMatrix: Matrix

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attrs: AttributeSet?) : this(context,
        attrs,
        0)

    constructor(context: Context, attrs: AttributeSet?, defStyle: Int): super(context, attrs, defStyle){
        initAttrs(context, attrs)
        initView()
    }

    //参数初始化
    private fun initAttrs(context: Context, attrs: AttributeSet?) {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundOvalImageView)
        mType = typedArray.getInteger(R.styleable.RoundOvalImageView_type, 0)
        mRoundRadius = typedArray.getDimensionPixelSize(R.styleable.RoundOvalImageView_radius, 10.toPx())
        typedArray.recycle()
    }

    private fun initView() {
        mPaint = Paint()
        mPaint.isAntiAlias = true
        mMatrix = Matrix()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        // 如果是绘制圆形，则强制宽高大小一致
        if (mType == TYPE_CIRCLE) {
            minSize = Math.min(measuredWidth, measuredHeight)
            mRadius = minSize / 2
            setMeasuredDimension(minSize, minSize)
        }
    }

    override fun onDraw(canvas: Canvas) {
        if (null == drawable) {
            return
        }
        setBitmapShader()
        if (mType == TYPE_CIRCLE) {
            canvas.drawCircle(mRadius.toFloat(), mRadius.toFloat(), mRadius.toFloat(), mPaint)
        } else if (mType == TYPE_ROUND) {
            canvas.drawRoundRect(mRect, mRoundRadius.toFloat(), mRoundRadius.toFloat(), mPaint)
        } else if (mType == TYPE_OVAL) {
            canvas.drawOval(mRect, mPaint)
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mRect = RectF(0f, 0f, width.toFloat(), height.toFloat())
    }

    /**
     * 设置BitmapShader
     */
    private fun setBitmapShader() {
        val drawable = drawable ?: return
        val bitmap: Bitmap = drawableToBitmap(drawable)
        // 将bitmap作为着色器来创建一个BitmapShader
        mBitmapShader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
        var scale = 1.0f
        if (mType == TYPE_CIRCLE) {
            // 拿到bitmap宽或高的小值
            val bSize: Int = Math.min(bitmap.width, bitmap.height)
            scale = minSize * 1.0f / bSize
        } else if (mType == TYPE_ROUND || mType == TYPE_OVAL) {
            // 如果图片的宽或者高与view的宽高不匹配，计算出需要缩放的比例；缩放后的图片的宽高，一定要大于我们view的宽高；所以我们这里取大值；
            scale = Math.max(width * 1.0f / bitmap.width,
                height * 1.0f / bitmap.height)
        }
        // shader的变换矩阵，我们这里主要用于放大或者缩小
        mMatrix.setScale(scale, scale)
        // 设置变换矩阵
        mBitmapShader.setLocalMatrix(mMatrix)
        mPaint.shader = mBitmapShader
    }

    /**
     * drawable转bitmap
     *
     * @paramdrawable
     * @return
     */
    private fun drawableToBitmap(drawable: Drawable): Bitmap {
        if (drawable is BitmapDrawable) {
            return drawable.bitmap
        }
        val w = drawable.intrinsicWidth
        val h = drawable.intrinsicHeight
        val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, w, h)
        drawable.draw(canvas)
        return bitmap
    }

}